package cn.chinaflame.pagodas.utils.email;

import java.util.Date;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;

import cn.chinaflame.pagodas.utils.Resources;

/**
 * 邮件引擎
 * 
 * @author ShenHuaJie
 * @version $Id: MailEntrance.java, v 0.1 2014年12月4日 下午8:34:48 ShenHuaJie Exp $
 */
@Component
public final class EmailSender {
	private final Logger logger = LoggerFactory.getLogger(EmailSender.class);

	private MimeMessage mimeMsg; // MIME邮件对象
	private Session session; // 邮件会话对象
	private Properties props; // 系统属性
	// 邮件发送协议 
    private final static String PROTOCOL = "smtp"; 
    // SMTP邮件服务器默认端口 
    private final static String PORT = "25"; 

	private Multipart mp; // Multipart对象,邮件内容,标题,附件等内容均添加到其中后再生成MimeMessage对象
	public EmailSender() {}
	public EmailSender(Email email) {
		try {
			if (props == null)
				props = System.getProperties(); // 获得系统属性对象
			props.setProperty("mail.transport.protocol", PROTOCOL); 
			props.setProperty("mail.smtp.host", email.getHost()); // 设置SMTP主机
//			props.put("mail.smtp.user", username);
			props.setProperty("mail.smtp.auth", email.getSmtpauth());
	        props.setProperty("mail.smtp.port", PORT); 
	        props.setProperty("mail.debug",email.getSmtpdebug()); 
	        props.setProperty("mail.encoding",email.getEncoding()); 
			createMimeMessage();
		} catch (Exception ex) {
			logger.error("", ex);
		}
	}


	/**
	 * 创建MIME邮件对象
	 * 
	 * @return boolean
	 */
	public boolean createMimeMessage() {
		try {
			session = Session.getDefaultInstance(props, null); // 获得邮件会话对象
		} catch (Exception e) {
			logger.error("获得邮件会话对象异常", e.getLocalizedMessage());
			return false;
		}
		try {
			mimeMsg = new MimeMessage(session); // 创建MIME邮件对象
			mp = new MimeMultipart();
			return true;
		} catch (Exception e) {
			logger.error("创建MIME邮件对象异常", e.getLocalizedMessage());
			return false;
		}
	}



	/**
	 * 设置主题
	 * 
	 * @param mailSubject String
	 * @return boolean
	 */
	public boolean setSubject(String mailSubject) {
		logger.info("setSubject:mailSubject:{}",mailSubject);
		try {
			mimeMsg.setSubject(mailSubject, "UTF-8");
			return true;
		} catch (Exception e) {
			logger.error("邮件主题设置异常", e);
			return false;
		}
	}

	/**
	 * 设置内容
	 * 
	 * @param mailBody String
	 */
	public boolean setBody(String mailBody) {
		logger.info("setBody:mailBody:{}",mailBody);
		try {
			BodyPart bp = new MimeBodyPart();
			bp.setContent("" + mailBody, "text/html;charset=UTF-8");
			mp.addBodyPart(bp);
			return true;
		} catch (Exception e) {
			logger.error("设置邮件内容异常", e);
			return false;
		}
	}

	/**
	 * 设置附件
	 * 
	 * @param name String
	 * @param pass String
	 */
	public boolean addFileAffix(String filename) {
		logger.info("addFileAffix:fileName:{}",filename);
		try {
			BodyPart bp = new MimeBodyPart();
			FileDataSource fileds = new FileDataSource(filename);
			bp.setDataHandler(new DataHandler(fileds));
			bp.setFileName(MimeUtility.encodeText(fileds.getName()));
			mp.addBodyPart(bp);
			return true;
		} catch (Exception e) {
			logger.error(filename, e);
			return false;
		}
	}

	/**
	 * 设置发信人
	 * 
	 * @param name String
	 * @param pass String
	 */
	public boolean setFrom(String from) {
		logger.info("from:{}",from);
		try {
			String[] f = from.split(",");
			if (f.length > 1) {
				from = MimeUtility.encodeText(f[0]) + "<" + f[1] + ">";
			}
			mimeMsg.setFrom(new InternetAddress(from)); // 设置发信人
			return true;
		} catch (Exception e) {
			logger.error(e.getLocalizedMessage());
			return false;
		}
	}

	/**
	 * 设置收信人
	 * 
	 * @param name String
	 * @param pass String
	 */
	public boolean setTo(String to) {
		logger.info("to:{}",to);
		if (to == null)
			return false;
		logger.info("设置邮件收信人", to);
		try {
			mimeMsg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
			return true;
		} catch (Exception e) {
			logger.error(e.getLocalizedMessage());
			return false;
		}
	}

	/**
	 * 设置抄送人
	 * 
	 * @param name String
	 * @param pass String
	 */
	public boolean setCopyTo(String copyto) {
		logger.info("copyto:{}",copyto);
		if (copyto == null)
			return false;
		logger.info("email.copyto={}", copyto);
		try {
			mimeMsg.setRecipients(Message.RecipientType.CC, (Address[]) InternetAddress.parse(copyto));
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * 发送邮件
	 * 
	 * @param name String
	 * @param pass String
	 */
	public boolean sendout(Email email) {
		logger.info("sendout：email:{}",JSONObject.toJSONString(email));
		try {
			mimeMsg.setContent(mp);
			mimeMsg.saveChanges();
			logger.info("email.sending={}",email.getSending());
			Session mailSession = Session.getInstance(props, new Authenticator() {
				protected PasswordAuthentication getPasswordAuthentication() {
					if (email.getUserkey() == null || "".equals(email.getUserkey().trim())) {
						return null;
					}
					return new PasswordAuthentication(email.getName(), email.getUserkey());
				}
			});
			Transport transport = mailSession.getTransport("smtp");
			transport.connect((String) props.get("mail.smtp.host"), email.getName(), email.getPassword());
			// 设置发送日期
			mimeMsg.setSentDate(new Date());
			// 发送
			transport.sendMessage(mimeMsg, mimeMsg.getRecipients(Message.RecipientType.TO));
			if (mimeMsg.getRecipients(Message.RecipientType.CC) != null) {
				transport.sendMessage(mimeMsg, mimeMsg.getRecipients(Message.RecipientType.CC));
			}
			logger.info("mail.sendSucc={}",email.getSendSucc());
			transport.close();
			return true;
		} catch (Exception e) {
			logger.error("mail.sendErr={}",email.getSendErr(), e);
			return false;
		}
	}
}
